﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine.Light;
using PloobsEngine.Modelo;
using PloobsEngine.Cameras;
using PloobsEngine.SceneControl;
using Microsoft.Xna.Framework;

namespace PloobsEngine.Material
{
    /// <summary>
    /// Forward Material
    /// </summary>
    public class TransparenteNormal : IShader
    {
        bool useTextureAlpha = true;
        float transparencyLevel = 0;
        Effect _shader;
        CullMode cullMode = CullMode.None;

        /// <summary>
        /// Default None
        /// </summary>
        public CullMode CullModeToUse
        {
            get { return cullMode; }
            set { cullMode = value; }
        }

        /// <summary>
        /// Between 0 and 1 
        /// If not setted, the texture alpha will be used instead
        /// </summary>
        public float TransparencyLevel
        {
            get { return transparencyLevel; }
            set { transparencyLevel = value; useTextureAlpha = false; }
        }
             

        public override MaterialType MaterialType
        {
            get { return MaterialType.FORWARD; }
        }        

        public override void Initialize()
        {
            _shader = EngineStuff.InternalContentManager.GetAsset<Effect>("TransparentEffect").Clone(EngineStuff.GraphicsDevice);
        }

        public override void PreUpdate(IObject ent, IList<ILight> lights)
        {
            _shader.Parameters["colorMap"].SetValue(ent.Modelo.getTexture(TextureType.DIFFUSE));                                    
            base.PreUpdate(ent, lights);
        }

        public override void PosDrawPhase(IModelo modelo, IRenderHelper render, ICamera cam, IList<ILight> lights)
        {
            DrawModel(modelo, cam);
        }

        private void DrawModel(IModelo modelo, ICamera cam)
        {
            if (obj != null)
            {

                Matrix[] boneTransforms = modelo.getBonesTransformation();
                Matrix wld = obj.getWorldMatrix();
                for (int i = 0; i < modelo.MeshNumber; i++)
                {
                    BatchInformation[] bi = modelo.GetBatchInformation(i);
                    Matrix w1 = Matrix.Multiply(wld, boneTransforms[modelo.GetParentBoneIndex(i)]);                    
                    _shader.Parameters["wvp"].SetValue(w1 * cam.View * cam.Projection);
                    for (int j = 0; j < bi.Count(); j++)
                    {
                        EngineStuff.GraphicsDevice.RenderState.CullMode = cullMode;
                        EngineStuff.GraphicsDevice.RenderState.AlphaBlendEnable = true;
                        EngineStuff.GraphicsDevice.RenderState.SourceBlend = Microsoft.Xna.Framework.Graphics.Blend.SourceAlpha;
                        EngineStuff.GraphicsDevice.RenderState.DestinationBlend = Microsoft.Xna.Framework.Graphics.Blend.InverseSourceAlpha;
                        //EngineStuff.GraphicsDevice.RenderState.ReferenceAlpha = 50; 

                        _shader.Parameters["alpha"].SetValue(transparencyLevel);
                        _shader.Parameters["useTextureAlpha"].SetValue(useTextureAlpha);                       

                        this._shader.Begin();
                        EngineStuff.GraphicsDevice.VertexDeclaration = bi[j].VertexDeclaration;
                        EngineStuff.GraphicsDevice.Vertices[0].SetSource(modelo.GetVertexBuffer(i), bi[j].StreamOffset, bi[j].VertexStride);
                        EngineStuff.GraphicsDevice.Indices = modelo.GetIndexBuffer(i);

                        this._shader.CurrentTechnique.Passes[0].Begin();
                        EngineStuff.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, bi[j].BaseVertex, 0, bi[j].NumVertices, bi[j].StartIndex, bi[j].PrimitiveCount);
                        this._shader.CurrentTechnique.Passes[0].End();
                        this._shader.End();
                    }

                }
            
                EngineStuff.GraphicsDevice.RenderState.AlphaBlendEnable = false;
                EngineStuff.GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = false;
                EngineStuff.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
            }
        }
    }
}
